﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using SymbolIntegration.core.Helpers;
using SymbolIntegration.core;
using Expression = SymbolIntegration.core.Expression;

namespace SymbolIntegration.ui
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            string error = "";
            do
            {
                if (IntgrExpressionTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, вираз";
                    break;
                }
                if (IntgrVarTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, змінну інтегрування";
                    break;
                }
                try
                {
                    var text = IntgrExpressionTextBox.Text;
                    var varText = IntgrVarTextBox.Text;
                    Expression expr = ParseUtils.ParseExpression(text);

                    var result = ExpressionFacade.Integrate(expr, varText);
                    IntgrResultTextBox.Text = result.Normalize().ToString();
                }
                catch (ParseException ex)
                {
                    error = "Помилка в виразі. Символ " + (ex.Position + ex.ErrorPosition) + ". Деталі помилки: " +
                            ex.Message;
                }
                catch (Exception ex)
                {
                    error = "Невідома помилка.  Деталі помилки: " + ex.Message;
                }
            } 
            while (false);
            SetStatus(error);
        }

        private void ButtonBase2_OnClick(object sender, RoutedEventArgs e)
        {
            string error = "";
            do
            {
                if (DiffExpressionTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, вираз";
                    break;
                }
                if (DiffVarTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, змінну диференціювання";
                    break;
                }
                try
                {
                    var text = DiffExpressionTextBox.Text;
                    var varText = DiffVarTextBox.Text;
                    Expression expr = ParseUtils.ParseExpression(text);
                    DiffResultTextBox.Text = expr.Differentiate(varText).Normalize().ToString();
                }
                catch (ParseException ex)
                {
                    error = "Помилка в виразі. Символ " + (ex.Position + ex.ErrorPosition) + ". Деталі помилки: " +
                            ex.Message;
                }
                catch (Exception ex)
                {
                    error = "Невідома помилка.  Деталі помилки: " + ex.Message;
                }
            }
            while (false);
            SetStatus(error);
            
        }

        private void ButtonBaseNorm_OnClick(object sender, RoutedEventArgs e)
        {
            string error = "";
            do
            {
                if (NormalExpressionTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, вираз";
                    break;
                }
                try
                {
                    var text = NormalExpressionTextBox.Text;
                    Expression expr = ParseUtils.ParseExpression(text);
                    NormalResultTextBox.Text = expr.Normalize().ToString();
                }
                catch (ParseException ex)
                {
                    error = "Помилка в виразі. Символ " + (ex.Position + ex.ErrorPosition) + ". Деталі помилки: " +
                            ex.Message;
                }
                catch (Exception ex)
                {
                    error = "Невідома помилка.  Деталі помилки: " + ex.Message;
                }
            }
            while (false);
            SetStatus(error);
        }

        private void MulButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
                        string error = "";
            do
            {
                if (MulIntgrVarTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, змінну інтегрування";
                    break;
                }
                if (MulIntgrVarXTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, змінну інтегрування";
                    break;
                }
                if (MulIntgrVarYTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, змінну інтегрування";
                    break;
                }

                if (MulIntgrXUpBoundTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, межі інтегрування";
                    break;
                }
                if (MulIntgrYUpBoundTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, межі інтегрування";
                    break;
                }
                if (MulIntgrZUpBoundTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, межі інтегрування";
                    break;
                }

                if (MulIntgrXDownBoundTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, межі інтегрування";
                    break;
                }
                if (MulIntgrYDownBoundTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, межі інтегрування";
                    break;
                }
                if (MulIntgrZDownBoundTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, межі інтегрування";
                    break;
                }

                if (MulIntgrExpressionTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, вираз";
                    break;
                }
                try
                {
                    var text = MulIntgrExpressionTextBox.Text;
                    Expression expr = ParseUtils.ParseExpression(text);
                    Expression Xexpr = ParseUtils.ParseExpression(MulIntgrVarTextBox.Text);
                    Expression Yexpr = ParseUtils.ParseExpression(MulIntgrVarXTextBox.Text);
                    Expression Zexpr = ParseUtils.ParseExpression(MulIntgrVarYTextBox.Text);

                    Expression XUp = ParseUtils.ParseExpression(MulIntgrXUpBoundTextBox.Text);
                    Expression YUp = ParseUtils.ParseExpression(MulIntgrYUpBoundTextBox.Text);
                    Expression ZUp = ParseUtils.ParseExpression(MulIntgrZUpBoundTextBox.Text);

                    Expression XDown = ParseUtils.ParseExpression(MulIntgrXDownBoundTextBox.Text);
                    Expression YDown = ParseUtils.ParseExpression(MulIntgrYDownBoundTextBox.Text);
                    Expression ZDown = ParseUtils.ParseExpression(MulIntgrZDownBoundTextBox.Text);

                    expr = ExpressionFacade.IntegrateWithBounds(expr, MulIntgrVarTextBox.Text, XUp, XDown);
                    Debug.WriteLine(expr.ToString());

                    expr = ExpressionFacade.IntegrateWithBounds(expr, MulIntgrVarXTextBox.Text, YUp, YDown);
                    Debug.WriteLine(expr.ToString());

                    expr = ExpressionFacade.IntegrateWithBounds(expr, MulIntgrVarYTextBox.Text, ZUp, ZDown);
                    Debug.WriteLine(expr.ToString());

                    MulIntgrResultTextBox.Text = expr.ToString();
                }
                catch (ParseException ex)
                {
                    error = "Помилка в виразі. Символ " + (ex.Position + ex.ErrorPosition) + ". Деталі помилки: " +
                            ex.Message;
                }
                catch (Exception ex)
                {
                    error = "Невідома помилка.  Деталі помилки: " + ex.Message;
                }
            }
            while (false);
            SetStatus(error);
        }

        private void SetStatus(string status)
        {
            StatusTextBlock.Text = status;
            if (status == "")
            {
                StatusTextBlock.Visibility = Visibility.Collapsed;
            }
            else
            {
                StatusTextBlock.Visibility = Visibility.Visible;
                StatusTextBlock.Background = new SolidColorBrush(Colors.Red);
            }
        }

        private void DiffDirection_OnClick(object sender, RoutedEventArgs e)
        {
            string error = "";
            do
            {
                if (XText.Text == "")
                {
                    error = "Введіть, будь ласка, x";
                    break;
                }
                if (YText.Text == "")
                {
                    error = "Введіть, будь ласка, y";
                    break;
                }
                if (ZText.Text == "")
                {
                    error = "Введіть, будь ласка, z";
                    break;
                }
                if (XVectorText.Text == "")
                {
                    error = "Введіть, будь ласка, x";
                    break;
                }
                if (YVectorText.Text == "")
                {
                    error = "Введіть, будь ласка, y";
                    break;
                }
                if (ZVectorText.Text == "")
                {
                    error = "Введіть, будь ласка, z";
                    break;
                }

                if (DiffDirectExpressionTextBox.Text == "")
                {
                    error = "Введіть, будь ласка, вираз";
                    break;
                }
                try
                {
                    var text = DiffDirectExpressionTextBox.Text;
                    Expression expr = ParseUtils.ParseExpression(text);
                    Expression Xexpr = ParseUtils.ParseExpression(XVectorText.Text);
                    Expression Yexpr = ParseUtils.ParseExpression(YVectorText.Text);
                    Expression Zexpr = ParseUtils.ParseExpression(ZVectorText.Text);
                    var dictVector = new Dictionary<string, Expression>();
                    dictVector.Add(XText.Text, Xexpr);
                    dictVector.Add(YText.Text, Yexpr);
                    dictVector.Add(ZText.Text, Zexpr);

                    DiffDirectionResultTextBox.Text = ExpressionFacade.DifferentiateByVector(expr, dictVector).ToString();
                }
                catch (ParseException ex)
                {
                    error = "Помилка в виразі. Символ " + (ex.Position + ex.ErrorPosition) + ". Деталі помилки: " +
                            ex.Message;
                }
                catch (Exception ex)
                {
                    error = "Невідома помилка.  Деталі помилки: " + ex.Message;
                }
            }
            while (false);
            SetStatus(error);
        }
    }
}
